//
// Created by LiangYu on 2018/8/24.
//
#include <dlfcn.h>
#include "common.h"
#include "net_liteheaven_hidefix_ReflectionHelper.h"
#include "fake_dlfcn.h"

#define LIB_ART_PATH "/system/lib/libart.so"
#define SYMBOL_SET_CLASS_LOADER "_ZN3art6mirror5Class14SetClassLoaderENS_6ObjPtrINS0_11ClassLoaderEEE"
#define SYMBOL_TO_CLASS "_ZN3art16WellKnownClasses7ToClassEP7_jclass"

typedef struct _ObjPtr{
    uintptr_t reference_;
}ObjPtr;

typedef void (*FUN_SET_CLASS_LOADER)(void*,void*);
typedef ObjPtr (*FUN_TO_CLASS)(jclass);

void hide_fix(JNIEnv* env){
    FUN_SET_CLASS_LOADER fun_set_class_loader = NULL;
    FUN_TO_CLASS fun_to_class = NULL;

    LOGI("hide_fix enter >>");

    int handle = fake_dlopen(LIB_ART_PATH, RTLD_NOW/*RTLD_LAZY*/);
    if (!handle){
        LOGI("fake_dlopen failed.");
        goto err_exit;
    }

    *(void**)(&fun_set_class_loader) = fake_dlsym(handle, SYMBOL_SET_CLASS_LOADER);
    if (!fun_set_class_loader){
        LOGI("fun_set_class_loader load failed.");
        goto err_exit;
    }

    *(void**)(&fun_to_class) = fake_dlsym(handle, SYMBOL_TO_CLASS);
    if (!fun_to_class){
        LOGI("fun_to_class load failed.");
        goto err_exit;
    }

    jclass clazz = (*env)->FindClass(env, "net/liteheaven/hidefix/ReflectionHelper");
    if (!clazz){
        LOGI("clazz of ReflectionHelper is null.");
        goto err_exit;
    }

    ObjPtr op = (*fun_to_class)(clazz);
    LOGI("op = %d", &op);
    (*fun_set_class_loader)((void*)op.reference_, NULL);

    fake_dlclose(handle);

err_exit:
    LOGI("hide_fix leave <<");
}

void Java_net_liteheaven_hidefix_ReflectionHelper_init(JNIEnv * env, jclass clazz){
    hide_fix(env);
}



